package com.minivision.sdktestdemo.controler.service;

import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.net.Uri;

import com.minivision.sdktestdemo.bean.MusicBean;
import com.minivision.sdktestdemo.event.PlayMusicEvent;
import com.minivision.sdktestdemo.model.MusicProvider;
import com.minivision.sdktestdemo.model.Provider;
import com.minivision.sdktestdemo.service.MusicService;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by devtang on 2016/4/18.
 */
public class MusicServiceControler {
    private MediaPlayer mPlayer;
    private MusicProvider mProvider;
    private List<MusicBean> mOrders;
    private PlayMusicEvent mMusicEvent;
    private boolean isPaused;

    public List<MusicBean> getPlayList() {
        return mOrders;
    }

    public void update() {
        mProvider.update();
    }

    public PlayMusicEvent getPlayingEvent() {
        return mMusicEvent;
    }

    public MusicServiceControler(MusicProvider provider) {
        mProvider = provider;
        mPlayer = new MediaPlayer();
        mMusicEvent = new PlayMusicEvent();
    }

    public void play(List<MusicBean> list) {
        mOrders.clear();
        mOrders.addAll(list);
//        if (mMusicEvent.mUri == null || mMusicEvent.mUri.isEmpty())
        if (list.size() > 0)
            mMusicEvent.setPlayEvent(new PlayMusicEvent(list.get(0), PlayMusicEvent.PLAY));
        Provider.setAllChanged(mProvider);
        EventBus.getDefault().post(mMusicEvent);
    }

    public boolean play(final PlayMusicEvent event) {
        if (mMusicEvent == null || !isPaused) {
            try {
                Provider.setAllChanged(mProvider);
                mPlayer.reset();
                mPlayer.setDataSource(event.mUri);
                mPlayer.prepare();
                mPlayer.start();
                mPlayer.setLooping(event.mOrder == MusicService.LOOP);
                mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        if (event.mOrder != MusicService.LOOP)
                            playNext(event);
                    }
                });
                if (mMusicEvent == null) {
                    mMusicEvent = event;
                } else {
                    mMusicEvent.setPlayEvent(event);
                }
                isPaused = false;
                return true;
            } catch (IOException e) {
                return false;
            }
        } else {
            mPlayer.start();
        }
        return false;
    }

    public void seekTo(int curPos) {
        if (mPlayer.isPlaying()) {
            mMusicEvent.mStatus = PlayMusicEvent.PLAY;
        } else {
            mMusicEvent.mStatus = PlayMusicEvent.PAUSE;
        }
        mPlayer.seekTo(curPos);
    }

    public void playNext(PlayMusicEvent event) {
        event.mStatus = PlayMusicEvent.PLAY;
        isPaused = false;
        mProvider.setChanged(true);
        EventBus.getDefault().post(getNext(event));
    }

    public void playPrev(PlayMusicEvent event) {
        event.mStatus = PlayMusicEvent.PLAY;
        isPaused = false;
        mProvider.setChanged(true);
        EventBus.getDefault().post(getPrev(event));
    }

    public void stop() {
        mMusicEvent.mStatus = PlayMusicEvent.STOP;
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
        }
        EventBus.getDefault().post(mMusicEvent);
    }

    private PlayMusicEvent getPrev(PlayMusicEvent event) {
        int position = indexOf(event.mUri);
        position = (mOrders.size() + position - 1) % mOrders.size();
        mMusicEvent.setPlayEvent(getPlayMusicEvent(mOrders.get(position)));
        return mMusicEvent;
    }

    public PlayMusicEvent getPlayMusicEvent(MusicBean bean) {
        Uri albumUri = bean.getmPicUri() == null ? Uri.EMPTY : bean.getmPicUri();
        PlayMusicEvent event = new PlayMusicEvent(bean.getmPath(),
                bean.getmMusicName(), bean.getmSingerName(),
                PlayMusicEvent.PLAY, albumUri, bean.getmLen());
        return event;
    }

    public PlayMusicEvent getPlayMusicEvent(int index) {
        return getPlayMusicEvent(mOrders.get(index));
    }

    public void pause() {
        isPaused = true;
        mMusicEvent.mStatus = PlayMusicEvent.PAUSE;
        mPlayer.pause();
    }

    public PlayMusicEvent getNext(PlayMusicEvent event) {
        int position = indexOf(event.mUri);
        position = (position + 1) % mOrders.size();
        mMusicEvent.setPlayEvent(getPlayMusicEvent(mOrders.get(position)));
        return mMusicEvent;
    }

    public int indexOf(String path) {
        int index = 0;
        for (MusicBean bean : mOrders) {
            if (bean.getmPath().equals(path)) {
                break;
            }
            ++index;
        }
        return index == mOrders.size() ? -1 : index;
    }

    public void generateOrder(int order) {
        if (mOrders == null) {
            mOrders = new ArrayList<MusicBean>(mProvider.size());
        }
        mOrders.clear();
        mOrders.addAll(mProvider.getList());
        if (order == MusicService.RAND) {
            Collections.shuffle(mOrders);
        }
    }

    public int getMaxProgress() {
        if (mMusicEvent == null || mMusicEvent.mUri.isEmpty()) {
            return mPlayer.getDuration();
        } else {
            return mMusicEvent.mDuration;
        }
    }

    public int getProgress() {
        if (mMusicEvent.mStatus != PlayMusicEvent.STOP) {
            int pos = mPlayer.getCurrentPosition();
            mMusicEvent.mCurPos = pos;
            return pos;
        } else {
            mMusicEvent.mCurPos = 0;
            return 0;
        }
    }

    public void release() {
        mPlayer.release();
        mPlayer = null;
        mProvider = null;
        mOrders = null;
        mMusicEvent = null;
    }

    public void remove(MusicBean bean) {
        int index = mOrders.indexOf(bean);
        if (mMusicEvent.mUri.equals(bean.getmPath())) {
            mMusicEvent.setPlayEvent(getPlayMusicEvent((index + 1) % mOrders.size()));
            if (!mPlayer.isPlaying()) {
                mMusicEvent.mStatus = PlayMusicEvent.STOP;
            }
            mMusicEvent.mUri = "";
            EventBus.getDefault().post(mMusicEvent);
        }
        mOrders.remove(index);
    }

    public void remove(List<MusicBean> beans) {
        Set<MusicBean> set = new HashSet<MusicBean>(beans);
        List<MusicBean> temp = new ArrayList<>(mOrders.size() - beans.size());
        for (MusicBean bean : mOrders) {
            if (!set.contains(bean)) {
                temp.add(bean);
            } else {
                if (mMusicEvent.mUri.equals(bean.getmPath())) {
                    if (!mPlayer.isPlaying()) {
                        mMusicEvent.mStatus = PlayMusicEvent.STOP;
                    }
                    mMusicEvent.mUri = "";
                }
            }
        }
        EventBus.getDefault().post(mMusicEvent);
        mOrders = temp;
    }

    public void save(SharedPreferences preferences) {
        if (mMusicEvent != null) {
            mMusicEvent.save(preferences);
        }
    }

    public void load(SharedPreferences preferences) {
        mMusicEvent.setPlayEvent(new PlayMusicEvent(preferences));
    }

    public void changeOrder(int order) {
        switch (order) {
            case MusicService.LOOP:
                mPlayer.setLooping(true);
                break;
            case MusicService.ALL:
            case MusicService.RAND:
                generateOrder(order);
                break;
        }
    }
}
